import os
import uuid
from flask import Flask, json, request, jsonify, Response, stream_with_context
from flask_cors import CORS
import oss2
from openai import OpenAI
from werkzeug.utils import secure_filename
from dotenv import load_dotenv

load_dotenv()

app = Flask(__name__)
CORS(app)

# 初始化OSS客户端
access_key_id = os.getenv('OSS_ACCESS_KEY_ID')
access_key_secret = os.getenv('OSS_ACCESS_KEY_SECRET')
bucket_name = os.getenv('OSS_BUCKET_NAME')
endpoint = os.getenv('OSS_ENDPOINT')

auth = oss2.Auth(access_key_id, access_key_secret)
bucket = oss2.Bucket(auth, endpoint, bucket_name)

def upload_to_oss(file):
    filename = secure_filename(file.filename)
    unique_filename = f"{uuid.uuid4()}_{filename}"
    content_type = 'application/octet-stream'  # 默认类型
    if filename.lower().endswith('.jpg') or filename.lower().endswith('.jpeg'):
        content_type = 'image/jpeg'
    elif filename.lower().endswith('.png'):
        content_type = 'image/png'
    elif filename.lower().endswith('.gif'):
        content_type = 'image/gif'
    bucket.put_object(unique_filename, file, headers={'Content-Type': content_type})
    url = f"http://img.xusun000.top/{unique_filename}"
    return url

@app.route('/upload', methods=['POST'])
def upload_image():
    if 'file' not in request.files:
        return jsonify({'error': 'No file part'}), 400
    file = request.files['file']
    if file.filename == '':
        return jsonify({'error': 'No selected file'}), 400
    try:
        url = upload_to_oss(file)
        return jsonify({'url': url})
    except Exception as e:
        return jsonify({'error': str(e)}), 500

@app.route('/chat', methods=['GET'])
def chat():
    # 从查询参数中获取 image_url、question、history 和其他可选参数
    image_url = request.args.get('image_url')
    question = request.args.get('question', '这是什么')  # 默认问题
    history = request.args.get('history', '[]')  # 默认为空历史
    temperature = request.args.get('temperature', default=1.0, type=float)  # 默认温度为 1.0
    max_tokens = request.args.get('max_tokens', default=None, type=int)  # 可选的最大 token 数
    top_p = request.args.get('top_p', default=None, type=float)  # 可选的 top_p 参数

    print(f"image_url: {image_url}, question: {question}, history: {history}, temperature: {temperature}, max_tokens: {max_tokens}, top_p: {top_p}")

    # 解析历史对话
    try:
        history = json.loads(history)
    except json.JSONDecodeError:
        return jsonify({'error': 'Invalid history format'}), 400

    # 初始化 OpenAI 客户端
    client = OpenAI(
        api_key=os.getenv("DASHSCOPE_API_KEY"),
        base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
    )
    
    # 构建完整的消息列表
    messages = [
        {
            "role": "system",
            "content": "如果我让你给出位置，请你按照以下格式给出并将结果：“ [左上角坐标x1, 左上角坐标y1, 右下角坐标x2, 右下角坐标y2] ”返回给我；如果我没有让你给出位置，那你就正常回答即可"
        },
        *history,  # 添加历史对话
        {
            "role": "user",
            "content": [
                {"type": "text", "text": question},
                {"type": "image_url", "image_url": {"url": image_url}}
            ]
        }
    ]

    try:
        # 调用 OpenAI 流式接口，并传递可选参数
        response = client.chat.completions.create(
            model="qwen-vl-plus",
            messages=messages,
            stream=True,  # 启用流式响应
            temperature=temperature,  # 温度参数
            max_tokens=max_tokens,  # 最大 token 数
            top_p=top_p  # top_p 参数
        )

        def generate():
            for chunk in response:
                content = chunk.choices[0].delta.content
                if content:
                    yield f"data: {content}\n\n"
            yield "data: [DONE]\n\n"

        return Response(stream_with_context(generate()), mimetype='text/event-stream')

    except Exception as e:
        return jsonify({'error': str(e)}), 500

if __name__ == '__main__':
    app.run(debug=True)